using System;
using System.Collections.Generic;
using Needle.Bus.Messages;

namespace Needle.Bus.Engine
{
    /// <summary>
    /// A message sink.
    /// </summary>
    public interface ISink : IEngineComponent, IHasCount
    {
        /// <summary>
        /// Enqueues the message, throws if the message is rejected.
        /// </summary>
        void Enqueue(IMessage message);

        /// <summary>
        /// Enqueues the messages, throws if the message is rejected.
        /// On rejection, all messages are rejected atomically.
        /// </summary>
        void Enqueue(IList<IMessage> messages);

        /// <summary>
        /// Enqueues the message, returns false if the message is rejected.
        /// </summary>
        bool TryEnqueue(IMessage message);

        /// <summary>
        /// Enqueues the messages, returns false if the messages are rejected.
        /// On rejection, all messages are rejected atomically.
        /// </summary>
        bool TryEnqueue(IList<IMessage> messages);

        /// <summary>
        /// Prepares the messages for enqueue, throws if the messages are 
        /// rejected. If the messages are accepted, Commit() will always 
        /// succeed in enqueueing the messages except when the sink has been 
        /// disposed before the commit.
        /// </summary>
        IDisposable PrepareForEnqueue(IList<IMessage> messages);

        /// <summary>
        /// commits the prepared messages to the sink, throws when the 
        /// sink has been disposed.
        /// </summary>
        void Commit(object transactionToken);

        /// <summary>
        /// discard the prepared messages, never throws.
        /// </summary>
        void Abort(object transactionToken);

        /// <summary>
        /// The filter that determines if messages 
        /// will be acctepted by this sink
        /// </summary>
        Predicate<IMessage> Filter {get; set;}
    
    }

}
